package org.moon.framework.autoconfigure.rabbitmq;

import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.moon.framework.autoconfigure.rabbitmq.config.MqttConfig;
import org.moon.framework.autoconfigure.rabbitmq.constant.MqttConstants;
import org.moon.framework.autoconfigure.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;

/**
 * mqtt相关配置
 */
@Configuration
@IntegrationComponentScan
@ConditionalOnProperty(value="moon.mqtt.enabled",havingValue = "true")
public class MqttAutoConfiguration {

    @Autowired
    private MqttConfig mqttConfig;

    /**
     * MQTT连接器选项
     * @return {@link MqttConnectOptions}
     */
    @Bean(name = MqttConstants.OPTIONS_NAME)
    public MqttConnectOptions mqttConnectOptions() {
        MqttConnectOptions options = new MqttConnectOptions();
        // 设置连接的用户名
        options.setUserName(mqttConfig.getUserName());
        // 设置连接的密码
        options.setPassword(mqttConfig.getPassword().toCharArray());
        options.setServerURIs(Func.toStrArray(mqttConfig.getUrls()));
        // 设置会话心跳时间，默认60秒。服务器会每隔（1.5 * KeepAlive）秒的时间向客户端发送心跳判断客户端是否在线，但这个方法并没有重连的机制
        options.setKeepAliveInterval(mqttConfig.getKeepAlive());
        // 设置是否清空session，false表示服务器会保留客户端的连接记录，true表示每次连接到服务器都以新的身份连接
        options.setCleanSession(true);
        // 允许同时发送的消息数量，默认10
        options.setMaxInflight(10);
        // 设置超时时间，默认30秒
        options.setConnectionTimeout(30);
        // 自动重连
        options.setAutomaticReconnect(true);
        return options;
    }

    /**
     * MQTT客户端
     * @param options {@link MqttConnectOptions}
     * @return {@link MqttPahoClientFactory}
     */
    @Bean(name = MqttConstants.FACTORY_NAME)
    public MqttPahoClientFactory mqttPahoClientFactory(
            @Qualifier(MqttConstants.OPTIONS_NAME) MqttConnectOptions options) {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(options);
        return factory;
    }
}
